﻿using Dora.Orm.SqlSugarCore.Reponsitory;
using Dora.Orm.SqlSugarCore.UnitOfWork;
using Dora.Services.AdminUser.Dto.QueryDto;
using Dora.Services.AdminUser.Dto.ViewDto;
using Dora.Services.AdminUser.Entities;
using Dora.Services.AdminUser.IApplication;
using Dora.Services.AdminUser.Repository;
using Dora.Services.AdminUser.Repository.Repositorys;
using Dora.Tools.Enums.AdminUser;
using Dora.Tools.Utility.Const;
using Dora.Tools.Utility.Redis;
using Microsoft.Extensions.Logging;
using Surging.Core.Common;
using Surging.Core.CPlatform.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dora.Services.AdminUser.Application.Base;

namespace Dora.Services.AdminUser.Application
{
    /// <summary>
    /// 系统表服务
    /// </summary>
    [ModuleName(DoraModuleName.AdminUser)]
    public class SystemInfoService : DoraServiceBase, ISystemInfoService
    {
        private readonly ILogger logger;
        private ISugarUnitOfWork unitOfWork;
        private SystemInfoRepository repository;
        private PermissionRepository permissionRepository;
        private DoraUserRepository doraUserRepository;
        public SystemInfoService(ISugarUnitOfWork _unitOfWork)
        {
            this.unitOfWork = _unitOfWork;
            repository = new SystemInfoRepository(unitOfWork);
            permissionRepository = new PermissionRepository(unitOfWork);
            doraUserRepository = new DoraUserRepository(unitOfWork);
        }


        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto<SystemInfoEntity>> Create(SystemInfoEntity entity)
        {
            try
            {

                if (string.IsNullOrWhiteSpace(entity.Name))
                {
                    return ResultDto<SystemInfoEntity>.Error("请输入系统名称");
                }

                if (string.IsNullOrWhiteSpace(entity.EnName))
                {
                    return ResultDto<SystemInfoEntity>.Error("请输入系统英文缩写");
                }

                var existEnName = await repository.ExistEnName(entity.Id, entity.EnName);
                if (existEnName)
                {
                    return ResultDto<SystemInfoEntity>.Error("英文缩写已经存在");
                }

                entity.SystemKey = $"{((SystemInfoType)entity.SystemType).ToString()}-{entity.EnName}".ToLower();
                var existGlobalKey = await repository.ExistSystemKey(entity.Id, entity.SystemKey);
                if (existGlobalKey)
                {
                    return ResultDto<SystemInfoEntity>.Error("系统Key已经存在");
                }

                entity.Id = await repository.GetMaxId() + 1;
                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                var result = await repository.InsertAsync(entity);
                if (result != null)
                {
                    return ResultDto<SystemInfoEntity>.Success(result);
                }
                else
                {
                    return ResultDto<SystemInfoEntity>.Error("创建失败");
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }


        /// <summary>
        /// 根据Id获取一个实体对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<SystemInfoEntity> GetById(int id)
        {
            return await repository.FirstOrDefaultAsync(id);
        }

        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageDataList<SystemInfoListDto>> GetPageList(SystemInfoQueryDto input)
        {
            var page = await repository.GetPageList(input);

            if (page.PageData?.Count() > 0 && input.IsLoadAllSub.HasValue && input.IsLoadAllSub.Value)
            {
                var systemIdList = page.PageData.Select(p => p.Id).ToList();
                //var moduleListAll = await _esmRepository.GetListBySystemIdList(systemIdList);
                var permissionListAll = await permissionRepository.GetListBySystemIdList(systemIdList);
                if (permissionListAll?.Count > 0)
                {
                    var moduleListAll = permissionListAll.Where(p => p.PType == (int)PermissionType.Module).ToList();
                    foreach (var system in page.PageData)
                    {
                        system.PType = (int)PermissionType.System;
                        if (moduleListAll?.Count > 0)
                        {
                            var moduleList = moduleListAll.FindAll(p => p.SystemId == system.Id);//菜单List
                            if (moduleList?.Count > 0)
                            {
                                system.SubList = moduleList;
                                foreach (var module in moduleList)
                                {
                                    if (permissionListAll.Count > 0)
                                    {
                                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                                        if (subListMenu?.Count > 0)
                                        {
                                            module.SubList = subListMenu;
                                            foreach (var item in subListMenu)
                                            {
                                                var subLists = permissionListAll.FindAll(p => p.ParentId == item.Id);//菜单下的权限列表
                                                item.SubList = subLists;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return page;
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto> Update(SystemInfoEntity entity)
        {

            var oldEntity = await repository.FirstOrDefaultAsync(entity.Id);
            if (oldEntity == null)
            {
                return ResultDto.Error("系统不存在");
            }

            if (string.IsNullOrWhiteSpace(entity.Name))
            {
                return ResultDto.Error("请输入系统名称");
            }

            if (string.IsNullOrWhiteSpace(entity.EnName))
            {
                return ResultDto.Error("请输入系统英文缩写");
            }

            var existEnName = await repository.ExistEnName(entity.Id, entity.EnName);
            if (existEnName)
            {
                return ResultDto.Error("英文缩写已经存在");
            }

            oldEntity.SystemType = entity.SystemType;
            oldEntity.Name = entity.Name;
            oldEntity.CnName = entity.CnName;
            oldEntity.EnName = entity.EnName;
            oldEntity.BucketName = entity.BucketName;
            oldEntity.Icon = entity.Icon;
            oldEntity.LogoUrl = entity.LogoUrl;
            oldEntity.FrontPort = entity.FrontPort;
            oldEntity.DevUrl = entity.DevUrl;
            oldEntity.TestUrl = entity.TestUrl;
            oldEntity.PreUrl = entity.PreUrl;
            oldEntity.ProUrl = entity.ProUrl;
            oldEntity.CodeUrl = entity.CodeUrl;
            oldEntity.HeaderIds = entity.HeaderIds;
            oldEntity.HeaderNames = entity.HeaderNames;
            oldEntity.Sort = entity.Sort;
            oldEntity.Remark = entity.Remark;
            oldEntity.UpdatedUserId = entity.UpdatedUserId;
            oldEntity.UpdatedUserName = entity.UpdatedUserName;
            oldEntity.UpdatedTime = DateTime.Now;

            try
            {
                var result = await repository.UpdateAsync(oldEntity);
                if (result)
                {
                    return ResultDto.Success("修改成功");
                }
                else
                {
                    return ResultDto.Error("修改失败");
                }
            }
            catch (Exception ex)
            {
                return ResultDto.Error("修改失败");
            }

        }

        /// <summary>
        /// 根据IdList获取列表
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public async Task<List<SystemInfoEntity>> GetList(List<int> idList)
        {
            if (idList == null || idList.Count == 0)
            {
                return new List<SystemInfoEntity>();
            }
            var list = await repository.GetAllListAsync(it => idList.Contains(it.Id));
            return list;
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<SystemInfoEntity>> GetAll()
        {
            var list = await repository.GetAllListAsync();
            return list;
        }

        /// <summary>
        /// 通过系统key获取系统信息
        /// </summary>
        /// <param name="systemKey"></param>
        /// <returns></returns>
        public async Task<SystemInfoEntity> GetBySystemKey(string systemKey)
        {
            return await repository.FirstOrDefaultAsync(it => it.SystemKey == systemKey);
        }

        /// <summary>
        /// 通过角色Id和系统Id获取所有的模块菜单和权限
        /// </summary>
        /// <param name="systemId"></param>
        /// <param name="roleId"></param>
        public async Task<List<PermissionListDto>> GetBySystemId(int systemId, Guid roleId)
        {
            //var moduleList = await _permissionRepository.GetListBySystemIdList(p=>p.IsDeleted==0&&p.SystemId==systemId);
            var moduleList = new List<PermissionListDto>();
            var permissionListAll = await permissionRepository.GetListBySystemIdList(new List<int>() { systemId });
            if (permissionListAll?.Count > 0)
            {
                moduleList = permissionListAll.FindAll(p => p.PType == (int)PermissionType.Module);
                if (roleId != Guid.Empty)
                {
                    #region 给角色拥有的权限打上标识
                    var selectedList = await permissionRepository.GetByRoleId(roleId);
                    if (selectedList?.Count > 0)
                    {
                        foreach (var item in permissionListAll)
                        {
                            var selectedItem = selectedList.Find(p => p.Id == item.Id);
                            item.IsSelected = false;
                            if (selectedItem != null)
                            {
                                item.IsSelected = true;
                            }
                        }
                    }
                    #endregion
                }
                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        if (subListMenu?.Count > 0)
                        {
                            if (subListMenu.Any(p => p.IsSelected))
                            {
                                module.IsSelected = true;
                            }
                            module.SubList = subListMenu;
                            foreach (var item in subListMenu)
                            {
                                var subLists = permissionListAll.FindAll(p => p.ParentId == item.Id);//菜单下的权限列表
                                item.SubList = subLists;
                            }
                        }
                    }
                }
            }
            return moduleList;
        }

        /// <summary>
        /// 获取当前登录用户某个系统的所有权限
        /// </summary>
        /// <param name="systemId"></param>
        /// <param name="roleId"></param>
        /// <param name="userId"></param>
        public async Task<List<PermissionListDto>> GetDoraAuthedBySystemId(int systemId, Guid roleId, Guid userId)
        {
            var permissionListAll = await permissionRepository.GetDoraAuthedListBySystemId(userId, systemId);
            if (permissionListAll == null || permissionListAll.Count == 0)
            {
                return new List<PermissionListDto>();
            }
            //var moduleIdList = permissionListAll.Select(p => p.ModuleId).Distinct().ToList();
            var moduleList = permissionListAll.Where(p => p.PType == (int)PermissionType.Module).ToList();//await _esmRepository.GetListByIdList(moduleIdList);
            if (moduleList?.Count > 0)
            {
                if (roleId != Guid.Empty)
                {
                    #region 给角色拥有的权限打上标识
                    var selectedList = await permissionRepository.GetByRoleId(roleId);
                    if (selectedList?.Count > 0)
                    {
                        foreach (var item in permissionListAll)
                        {
                            var selectedItem = selectedList.Find(p => p.Id == item.Id);
                            item.IsSelected = false;
                            if (selectedItem != null)
                            {
                                item.IsSelected = true;
                            }
                        }
                    }
                    #endregion
                }

                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        if (subListMenu?.Count > 0)
                        {
                            if (subListMenu.Any(p => p.IsSelected))
                            {
                                module.IsSelected = true;
                            }
                            module.SubList = subListMenu;
                            foreach (var item in subListMenu)
                            {
                                var subLists = permissionListAll.FindAll(p => p.ParentId == item.Id);//菜单下的权限列表
                                item.SubList = subLists;
                            }
                        }
                    }
                }
            }
            return moduleList;
        }

        public async Task<List<PermissionListDto>> GetAuthedMenuList(Guid userId, int systemId)
        {
            var permissionListAll = await permissionRepository.GetDoraAuthedListBySystemId(userId, systemId);
            if (permissionListAll == null || permissionListAll.Count() == 0)
            {
                return new List<PermissionListDto>();
            }
            //var moduleIdList = permissionListAll.Select(p => p.ModuleId).Distinct().ToList();
            var moduleList = permissionListAll.Where(p => p.PType == (int)PermissionType.Module).ToList();//await _esmRepository.GetListByIdList(moduleIdList);

            if (moduleList?.Count > 0)
            {
                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        module.SubList = subListMenu;
                    }
                }
            }
            return moduleList;
        }

        public async Task<List<PermissionListDto>> GetAllMenu(int systemId)
        {
            //var systemIdList = new List<int>() { systemId };
            var permissionListAll = await permissionRepository.GetBySystemId(systemId);
            var moduleList = permissionListAll.Where(p => p.PType == (int)PermissionType.Module).ToList(); //await _esmRepository.GetListBySystemIdList(systemIdList);

            if (moduleList?.Count > 0)
            {
                foreach (var module in moduleList)
                {
                    if (permissionListAll.Count > 0)
                    {
                        var subListMenu = permissionListAll.FindAll(p => p.ParentId == module.Id && p.PType == (int)PermissionType.Menu);//菜单List
                        module.SubList = subListMenu;
                    }
                }
            }
            else
            {
                moduleList = new List<PermissionListDto>();
            }
            return moduleList;
        }

        public async Task<int> ImportList(List<SystemInfoEntity> list)
        {
            if (list == null || list.Count == 0)
            {
                return 0;
            }
            var num = 0;
            foreach (var item in list)
            {
                var entity = await GetById(item.Id);
                if (entity == null)
                {
                    #region create
                    item.CreatedTime = DateTime.Now;
                    item.UpdatedTime = DateTime.Now;
                    var result = await repository.InsertAsync(item);
                    if (result != null)
                    {
                        num++;
                    }
                    #endregion
                }
                else
                {
                    #region update
                    item.UpdatedTime = DateTime.Now;
                    var result = await repository.UpdateAsync(item);
                    if (result)
                    {
                        num++;
                    }
                    #endregion
                }
            }
            return num;
        }

        //public async Task<List<SystemInfoEntity>> GetAuthedList(Guid userId)
        //{
        //    var isDevEmp = false;
        //    var systemIdList = new List<Guid>() { Guid.Empty};
        //    var permissionListAll = await _permissionRepository.GetDoraAuthedListByUserId(userId);
        //    if (permissionListAll?.Count() > 0)
        //    {
        //        systemIdList = permissionListAll.Select(p => p.SystemId).Distinct().ToList();
        //    }

        //    //判断是否是技术人员
        //    var deptList = await _employeeDepartmentRepository.GetListByEmployeeId(EmployeeId);
        //    if (deptList?.Count > 0 && deptList.Where(p => p.DTId == ConstValue.TechDeptDTId).FirstOrDefault() != null)
        //    {
        //        isDevEmp = true;
        //    }

        //    var systemList = await _repository.GetAuthedList(systemIdList, isDevEmp);
        //    //if (systemIdList?.Count > 0)
        //    //{
        //    //    foreach (var item in systemIdList)
        //    //    {

        //    //    }
        //    //}
        //    return systemList;
        //}

        /// <summary>
        /// 刷新系统菜单
        /// </summary>
        /// <param name="systemKey"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<bool> DoraRefreshMenuCache(string systemKey, Guid userId)
        {
            var employee = await doraUserRepository.FirstOrDefaultAsync(userId);
            if (employee == null)
            {
                return false;
            }

            //不存在则不用刷新
            if (!await SystemMenuCacheHelper.Exist(systemKey, userId))
            {
                return false;
            }

            Console.WriteLine($"RefreshMenuCache SystemId:{systemKey} EmployeeId:{userId}");

            var modelSystem = await GetBySystemKey(systemKey);
            if (modelSystem == null)
            {
                Console.WriteLine("未找到系统");
                return false;
            }
            var moduleList = new List<PermissionListDto>();
            if (employee.IsSuperAdmin == 1)
            {
                moduleList = await GetAllMenu(modelSystem.Id);
            }
            else
            {
                moduleList = await GetAuthedMenuList(userId, modelSystem.Id);
            }

            var menuList = new List<dynamic>();
            if (moduleList?.Count > 0)
            {
                foreach (var item in moduleList)
                {
                    var obj = new { item.Id, item.AuthKey, item.Name, item.Icon, item.Sort };
                    menuList.Add(obj);
                    if (item.SubList?.Count > 0)
                    {
                        foreach (var itemSub in item.SubList)
                        {
                            var sub = new { itemSub.Id, itemSub.AuthKey, itemSub.Name, Icon = "", itemSub.Sort };
                            menuList.Add(sub);
                        }
                    }
                }
            }
            await SystemMenuCacheHelper.Set(systemKey, userId, menuList);
            return true;
        }

    }
}
